home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
DEMO_VGA
/
FRSTM1.LZH
/
FRSTM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-27
|
16KB
|
588 lines
#include <graph.h>
#include <dos.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include "xbit.h"
#include "chkpoint.h"
int VgaWonder = 0, ATIProduct = 1;
struct _COMPLEX {
double i, j;
};
unsigned int Iterations, LineColor = 200;
unsigned char far *ColorLog;
void savetodisk(char *filename, int xdots, int ydots, int colors);
struct _COLOR_GUNS GIFColorTable[256];
struct _MALSET {
char FileName[40], Title[80];
struct _COMPLEX Offset, Aspect;
long ltime, Current, NumPasses, PassesLeft, NumPassed;
long Hours, Minutes, Seconds;
union _FIXED32BIT AspectX, AspectY, it, jt, Creal, Cimag;
double HLength, VLength, Scale, Delta, Overlap;
int OverflowMask, SigDigits, PassMode, Colors, Direct, BPL, InSetMask;
int JuliaFlag, EndTime;
int Midx, Midy, Overflow, NumRep, Mousex, Mousey, Mult, Buttons, DefColors;
struct videoconfig Vid;
};
typedef struct _MALSET *MALSET;
void ClearScreen(void) {
union REGS Regs;
if(VgaWonder) {
Regs.x.ax = 0x63;
int86(0x10, &Regs, &Regs);
}
else
_clearscreen(_GCLEARSCREEN);
}
void ClearScreen(void);
void MarkTimeLeft(MALSET m) {
struct tm *t;
union REGS Regs;
Regs.h.ah = 3;
Regs.h.bh = 0;
int86(0x10, &Regs, &Regs);
printf("%02ld:%02ld:%02ld ", m->Hours, m->Minutes, m->Seconds);
t = localtime(&m->Current);
if(m->EndTime) {
m->Seconds += t->tm_sec;
m->Minutes += m->Seconds / 60;
m->Seconds %= 60;
m->Minutes += t->tm_min;
m->Hours += m->Minutes / 60;
m->Minutes %= 60;
m->Hours += t->tm_hour;
m->Hours %= 24;
}
else {
m->Seconds = m->Current - m->ltime;
m->Hours = m->Seconds / 3600;
m->Seconds %= 3600;
m->Minutes = m->Seconds / 60;
m->Seconds %= 60;
}
printf("%02ld:%02ld:%02ld ", m->Hours, m->Minutes, m->Seconds);
Regs.h.ah = 2;
int86(0x10, &Regs, &Regs);
}
/* Add these as a global work space */
unsigned int ScreenLines, PixelsPerLine, ScanLineOff = 16;
int MultiPass(MALSET m, int Initx, int Inity, int Shift) {
if(Shift != m->Mult) {
if(!MultiPass(m, Initx, Inity, Shift << 1)) {
if(!MultiPass(m, Initx + Shift, Inity + Shift, Shift << 1)) {
if(!MultiPass(m, Initx + Shift, Inity, Shift << 1))
return(MultiPass(m, Initx, Inity + Shift, Shift << 1));
}
}
}
else {
DoubleToXBit(m->Aspect.i * m->Mult, m->AspectX.C);
DoubleToXBit(-m->Aspect.j * m->Mult, m->AspectY.C);
DoubleToXBit((-m->Aspect.i * m->Midx) + m->Offset.i +
(m->Aspect.i * Initx), m->it.C);
DoubleToXBit((m->Aspect.j * m->Midy) + m->Offset.j -
(m->Aspect.j * (Inity + ScanLineOff)), m->jt.C);
time(&m->Current);
if(m->NumPassed) {
m->Seconds = m->Current - m->ltime;
m->PassesLeft = m->NumPasses - m->NumPassed;
m->Seconds = m->PassesLeft * ((m->Seconds * 0x1000) / m->NumPassed);
m->Seconds /= 0x1000;
m->Hours = m->Seconds / 3600;
m->Minutes = (m->Seconds - (m->Hours * 3600)) / 60;
m->Seconds -= (m->Hours * 3600) + (m->Minutes * 60);
MarkTimeLeft(m);
}
m->NumPassed++;
/* Fixes problem when 'm->Mult' does not divide evenly into pixel count */
ScreenLines = (m->Vid.numypixels - ScanLineOff) / m->Mult;
if(Inity < ((m->Vid.numypixels - ScanLineOff) % m->Mult))
ScreenLines++;
PixelsPerLine = m->Vid.numxpixels / m->Mult;
if(Initx < (m->Vid.numxpixels % m->Mult))
PixelsPerLine++;
return(DrawMandelbrot(m->it.L, m->jt.L, Iterations, m->NumRep,
m->AspectX.L, m->AspectY.L, PixelsPerLine, ScreenLines,
m->OverflowMask, m->SigDigits, m->BPL, Initx,
Inity + ScanLineOff, m->Mult, m->BPL * (m->Mult - 1),
m->Mousex, m->Mousey, m, ColorLog,
m->Buttons, m->Direct, m->InSetMask, m->JuliaFlag,
m->Creal.L, m->Cimag.L));
}
}
void far MouseRoutine(struct _MALSET far *m, int x, int y, int Buttons);
void SetPalReg(int n, unsigned char Red, unsigned char Green,
unsigned char Blue) {
union REGS Regs;
Regs.h.ah = 0x10;
Regs.h.al = 0x10;
GIFColorTable[n].Red = (Regs.h.dh = Red) << 2;
GIFColorTable[n].Blue = (Regs.h.cl = Blue) << 2;
GIFColorTable[n].Green = (Regs.h.ch = Green) << 2;
Regs.x.bx = n;
int86(0x10, &Regs, &Regs);
}
void SetPalette(MALSET m) {
union REGS Regs;
double RedAngle, GreenAngle, BlueAngle, TwoPi, TwoThirdsPi, Fudge;
unsigned char Red, Green, Blue;
unsigned n;
if(!m->DefColors) {
for(n = 0; n < 256; n++) {
Regs.h.ah = 0x10;
Regs.h.al = 0x15;
Regs.x.bx = n;
int86(0x10, &Regs, &Regs);
GIFColorTable[n].Red = Regs.h.dh << 2;
GIFColorTable[n].Green = Regs.h.ch << 2;
GIFColorTable[n].Blue = Regs.h.cl << 2;
}
return;
}
ClearScreen();
_settextcolor(200);
printf("Setting palette");
TwoPi = asin(1.0) * 4.0;
TwoThirdsPi = TwoPi / 3.0;
Fudge = asin(1.0) / 2.5;
for(n = 1; n < 256; n++) {
BlueAngle = (TwoPi / (255.0 / m->Overlap)) * (float)((long)n) + Fudge;
GreenAngle = BlueAngle + TwoThirdsPi;
RedAngle = GreenAngle + TwoThirdsPi;
Red = (unsigned char)((long)(((cos(RedAngle) + 1.0) * 31.5) + 0.5));
Blue = (unsigned char)((long)(((cos(BlueAngle) + 1.0) * 31.5) + 0.5));
Green = (unsigned char)((long)(((cos(GreenAngle) + 1.0) * 31.5) + 0.5));
SetPalReg(n, Red, Green, Blue);
}
}
void ClipLine(struct _MALSET far *m, int x1, int y1, int x2, int y2) {
if((x1 < m->Vid.numxpixels) && (y1 < m->Vid.numypixels) &&
(x2 >= 0) && (y2 >= 0)) {
if(x1 < 0)
x1 = 0;
if(y1 < 0)
y1 = 0;
if(x2 >= m->Vid.numxpixels)
x2 = m->Vid.numxpixels;
if(y2 >= m->Vid.numypixels)
y2 = m->Vid.numypixels;
if(x1 == x2)
ATIxorLine(x1, y1, m->Vid.numxpixels, y2 - y1, m->Vid.numxpixels);
else
ATIxorLine(x1, y1, 1, x2 - x1, m->Vid.numxpixels);
}
}
void MouseCursor(struct _MALSET far *m, int x, int y) {
ClipLine(m, x - 5, y, x + 6, y);
ClipLine(m, x, y - 5, x, y + 6);
}
void far MouseRoutine(struct _MALSET far *m, int x, int y, int Buttons) {
double i, j;
clock_t tick;
union REGS Regs, Pos;
Pos.h.ah = 3;
Pos.h.bh = 0;
int86(0x10, &Pos, &Pos);
if(m->Mousex != -1)
MouseCursor(m, m->Mousex, m->Mousey);
m->Mousex = x;
m->Mousey = y;
i = (m->Aspect.i * (x - m->Midx)) + m->Offset.i;
j = (m->Aspect.j * (m->Midy - y)) + m->Offset.j;
Regs.h.ah = 2;
Regs.h.bh = 0;
if(VgaWonder) {
Regs.h.dh = 0;
Regs.h.dl = 40;
}
else {
Regs.h.dh = 1;
Regs.h.dl = 0;
}
int86(0x10, &Regs, &Regs);
printf("i = %+01.8f, j = %+01.8f", i, j,
m->Scale * m->Delta);
Pos.h.ah = 2;
int86(0x10, &Pos, &Pos);
MouseCursor(m, x, y);
tick = clock();
while(clock() == tick);
}
void SetupMouse(MALSET m) {
union REGS Regs;
Regs.x.ax = 0;
int86(0x33, &Regs, &Regs);
Regs.x.ax = 4;
Regs.x.cx = m->Midx;
Regs.x.dx = m->Midy;
int86(0x33, &Regs, &Regs);
Regs.x.ax = 7;
Regs.x.cx = 0;
Regs.x.dx = m->Vid.numxpixels - 1;
int86(0x33, &Regs, &Regs);
Regs.x.ax = 8;
Regs.x.cx = 0;
Regs.x.dx = m->Vid.numypixels - 1;
}
void Malset(MALSET m) {
char Str[140];
struct tm *t;
int Done = 0, n;
union REGS Regs;
m->Mult = (1 << (m->PassMode - 1));
m->Mousex = -1;
m->Buttons = 0;
m->Delta = 1.0;
SetPalette(m);
m->NumPassed = 0L;
m->NumPasses = (long)m->Mult * m->Mult;
time(&m->ltime);
Regs.h.ah = 2;
Regs.x.dx = 0;
Regs.h.bh = 0;
int86(0x10, &Regs, &Regs);
SetupMouse(m);
MultiPass(m, 0, 0, 1);
t = localtime(&m->ltime);
Regs.h.ah = 2;
Regs.x.dx = 0;
Regs.h.bh = 0;
int86(0x10, &Regs, &Regs);
MouseCursor(m, m->Mousex, m->Mousey);
/* printf("%80s", " ");
Regs.h.ah = 2;
Regs.x.dx = 0;
Regs.h.bh = 0;
int86(0x10, &Regs, &Regs);
if(VgaWonder)
printf("%s, %d/%d/%d", m->Title, t->tm_mon + 1, t->tm_mday, t->tm_year);
else {
printf("%s\n", m->Title);
printf("%d/%d/%d", t->tm_mon + 1, t->tm_mday, t->tm_year);
} */
}
void PrintTitle(void) {
_clearscreen(_GCLEARSCREEN);
printf("Fire Storm Drawing Program - Version 1.0\n");
printf(" -by Mark C. Peterson\n");
printf(" CompuServe [70441,3353]\n");
printf("Program resides in the public domain.\n\n");
}
void PrintTitle(void);
char *Get(char *Response) {
union REGS Regs;
Regs.h.ah = 3;
Regs.h.bh = 0;
int86(0x10, &Regs, &Regs);
gets(Response);
Regs.h.ah = 2;
int86(0x10, &Regs, &Regs);
return(Response);
}
void GetDefaults(MALSET m) {
double d;
char Response[200];
SetXBit(4, 2);
m->HLength = 10.0;
m->VLength = 7.0;
printf("Exit instructions:\n");
printf(" Ctrl-C during quiry.\n");
printf(" 'Esc' three times while drawing.\n\n");
if(VgaWonder) {
printf("Use 800x600x256 mode ('y' default)? ");
Get(Response);
if((Response[0] == 'n') || (Response[0] == 'N'))
VgaWonder = 0;
else
printf("Yes");
printf("\n");
}
printf("Significant binary digits (1 -> 29, 13 default)? ");
m->SigDigits = atoi(Get(Response));
if(!m->SigDigits)
m->SigDigits = 13;
if(m->SigDigits < 1)
m->SigDigits = 1;
if(m->SigDigits > 29)
m->SigDigits = 29;
printf("%d \n", m->SigDigits);
printf("Pattern repetition threshold (1 -> 65535, 2 default)? ");
if(!(m->NumRep = atoi(Get(Response))))
m->NumRep = 2;
printf("%d \n", m->NumRep);
printf("Iteration threshold (1 -> 65535, 500 default)? ");
if(!(Iterations = atoi(Get(Response))))
Iterations = 500;
printf("%u \n", Iterations);
printf("Scale (0.45 maximum and default)? ");
m->Scale = atof(Get(Response));
if((m->Scale > 0.45) || (m->Scale <= 0.0))
m->Scale = 0.45;
printf("%01.8f \n", m->Scale);
printf("i Offset (0.0 default)? ");
m->Offset.i = atof(Get(Response));
printf("%01.8f \n", m->Offset.i);
printf("j Offset (0.0 default)? ");
m->Offset.j = atof(Get(Response));
printf("%01.8f \n", m->Offset.j);
printf("Mandelbrot set ('y' default)? ");
Get(Response);
if((Response[0] == 'n') || (Response[0] == 'N')) {
m->JuliaFlag = 1;
printf("\nJulia i? ");
d = atof(Get(Response));
DoubleToXBit(d, m->Creal.C);
d = XBitToDouble(m->Creal.C);
printf("%01.8f \nJulia j? ", d);
d = atof(Get(Response));
DoubleToXBit(d, m->Cimag.C);
d = XBitToDouble(m->Cimag.C);
printf("%01.8f ", d);
}
else {
m->JuliaFlag = 0;
printf("Yes ");
}
printf("\n");
printf("Display overflows ('y' default)? ");
Get(Response);
if((Response[0] == 'n') || (Response[0] == 'N'))
m->OverflowMask = 0;
else {
m->OverflowMask = 0xff;
m->Colors = 256;
printf("Yes\nSmooth chromatic gradient ('y' default)? ");
Get(Response);
if((Response[0] == 'n') || (Response[0] == 'N')) {
m->DefColors = 0;
printf("No \n");
}
else {
m->DefColors = 1;
printf("Yes\n");
printf("Number of scale color overlaps (1.0 default)? ");
m->Overlap = atof(Get(Response));
if(!m->Overlap)
m->Overlap = 1.0;
printf("%g \n", m->Overlap);
}
printf("Display set interior ('n' default)? ");
Get(Response);
if((Response[0] == 'y') || (Response[0] == 'Y'))
m->InSetMask = -1;
else {
m->InSetMask = 0;
printf("No");
}
}
printf("\n");
printf("Multiple passes mode (1 -> 6, 6 default)? ");
m->PassMode = atoi(Get(Response));
if(!m->PassMode || (m->PassMode > 6))
m->PassMode = 6;
if(m->PassMode < 1)
m->PassMode = 1;
printf("%d\n", m->PassMode);
printf("Name of GIF file ('frstm.gif' default)? ");
if(!strcpy(m->FileName, Get(Response))[0])
strcpy(m->FileName, "frstm.gif");
printf("%s \n", m->FileName);
printf("Title (Coord info default)? ");
strcpy(m->Title, Get(Response));
if(!m->Title[0])
if(m->JuliaFlag)
sprintf(m->Title, "%1.8f + %1.8f",
XBitToDouble(m->Creal.C), XBitToDouble(m->Cimag.C));
else
sprintf(m->Title, "%1.8f + %1.8f, %1.6f", m->Offset.i,
m->Offset.j, m->Scale);
printf("%s \n", m->Title);
printf("Time display (1 = Time spent, 2 = Ending time)? ");
m->EndTime = atoi(Get(Response)) & 1;
ClearScreen();
}
void SetVideo(MALSET m) {
union REGS Regs;
if(VgaWonder) {
Regs.x.ax = 0x63;
int86(0x10, &Regs, &Regs);
m->Vid.numxpixels = 800;
m->Vid.numypixels = 600;
}
else {
if(!_setvideomode(_MRES256COLOR)) {
printf("Sorry, VGA required for this version.\n\n");
exit(1);
}
_getvideoconfig(&m->Vid);
}
}
void ChkForVgaWonder(void) {
char far *ATISigLoc = (char far *)0xc0000031;
char far *VgaWonderLoc = (char far *)0xc0000040;
static char ATIStr[] = "761295520";
static char VgaWonderStr[] = "31";
unsigned n;
for(n = 0; ATIStr[n]; n++) {
if(ATIStr[n] != ATISigLoc[n])
ATIProduct = 0;
}
if(ATIProduct) {
for(n = 0; VgaWonderStr[n]; n++) {
if(VgaWonderStr[n] != VgaWonderLoc[n])
return;
}
VgaWonder = GetATIConfig();
VgaWonder = (VgaWonder >= 0x25);
}
}
void ChkForVgaWonder(void);
void main(void) {
FILE *LogFile;
char LogFileName[20];
double LogIter, LogColor;
MALSET m;
union REGS Regs;
unsigned n, Done = 0;
m = calloc(1, sizeof(struct _MALSET));
ChkForVgaWonder();
PrintTitle();
SetVideo(m);
_setvideomode(_DEFAULTMODE);
GetDefaults(m);
SetVideo(m);
m->Direct = 1;
m->BPL = m->Vid.numxpixels;
m->Midx = m->Vid.numxpixels / 2;
m->Midy = m->Vid.numypixels / 2;
m->Aspect.i = (m->Scale * m->HLength) / m->Vid.numxpixels;
m->Aspect.j = (m->Scale * m->VLength) / m->Vid.numypixels;
while(kbhit())
getch();
Regs.h.ah = 2;
Regs.h.bh = 0;
Regs.x.dx = 0;
int86(0x10, &Regs, &Regs);
ColorLog = _fmalloc(Iterations);
sprintf(LogFileName, "%u.lgt", Iterations);
if(!(LogFile = fopen(LogFileName, "rb+"))) {
printf(" Computing Color Table");
LogIter = log((double)((float)((unsigned long)(Iterations))));
for(n = 1; n < Iterations; n++) {
if(!(n % 100)) {
Regs.h.ah = 2;
Regs.h.bh = 0;
Regs.x.dx = 0;
int86(0x10, &Regs, &Regs);
printf("%u", n);
}
LogColor = log((double)((float)((unsigned long)(n)))) / LogIter;
LogColor *= (double)((float)((unsigned long)m->Colors));
ColorLog[n - 1] = (unsigned char)((unsigned long)((float)(LogColor)));
}
LogFile = fopen(LogFileName, "wb+");
for(n = 0; n < Iterations; n++)
putc(ColorLog[n], LogFile);
fclose(LogFile);
}
else {
for(n = 0; n < Iterations; n++)
ColorLog[n] = (unsigned char)getc(LogFile);
fclose(LogFile);
}
if(!m->DefColors) {
for(n = 16; n < 256; n++)
ColorLog[n] = (unsigned char)(255 - ColorLog[n]);
}
Malset(m);
while(kbhit())
getch();
savetodisk(m->FileName, m->Vid.numxpixels, m->Vid.numypixels, 256);
while(!Done) {
if(kbhit()) {
if(getch() == 27)
Done = 1;
}
}
_setvideomode(_DEFAULTMODE);
}